﻿using AutoMapper;
using B.S.Medical.Api.Read.Application.Command.Register;
using B.S.Medical.Api.Read.DTOS;
using B.S.Medical.Domain.Department;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.Domain.Medical;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Read.Application.Handler.Register
{
    /// <summary>
    /// 挂号详情业务
    /// </summary>
    public class ShowRegisterDetailHandler : IRequestHandler<ShowRegisterDetailCommand, ApiResult<RegisterDetailDto>>
    {
        private readonly IBaseRepository<RegisterModel> _registerRepository;
        private readonly IBaseRepository<PatientModel> _patientRepository;
        private readonly IBaseRepository<DoctorModel> _doctorRepository;
        private readonly IBaseRepository<ManageModel> _departmentRepository;
        private readonly IBaseRepository<CampusModel> _campusRepository;
        private readonly IBaseRepository<JobTitleModel> _jobTitleRepository;
        private readonly IBaseRepository<registrationModel> _registrationRepository;
        private readonly ILogger<ShowRegisterDetailHandler> _logger;
        private readonly IMapper _mapper;

        public ShowRegisterDetailHandler(
            IBaseRepository<RegisterModel> registerRepository,
            IBaseRepository<PatientModel> patientRepository,
            IBaseRepository<DoctorModel> doctorRepository,
            IBaseRepository<ManageModel> departmentRepository,
            IBaseRepository<CampusModel> campusRepository,
            IBaseRepository<JobTitleModel> jobTitleRepository,
            IBaseRepository<registrationModel> registrationRepository,
            ILogger<ShowRegisterDetailHandler> logger,
            IMapper mapper)
        {
            _registerRepository = registerRepository;
            _patientRepository = patientRepository;
            _doctorRepository = doctorRepository;
            _departmentRepository = departmentRepository;
            _campusRepository = campusRepository;
            _jobTitleRepository = jobTitleRepository;
            _registrationRepository = registrationRepository;
            _logger = logger;
            _mapper = mapper;
        }

        public async Task<ApiResult<RegisterDetailDto>> Handle(ShowRegisterDetailCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 使用联表查询一次性获取所有相关数据
                var query = from register in _registerRepository.GetAll().Where(r => r.Id == request.Id && !r.IsDeleted)
                            join patient in _patientRepository.GetAll().Where(p => !p.IsDeleted)
                                on register.PatientId equals patient.Id
                            join doctor in _doctorRepository.GetAll().Where(d => !d.IsDeleted)
                                on register.DoctorId equals doctor.Id
                            join department in _departmentRepository.GetAll().Where(d => !d.IsDeleted)
                                on doctor.DepartmentId equals department.Id
                            join campus in _campusRepository.GetAll().Where(c => !c.IsDeleted)
                                on doctor.CampusId equals campus.Id
                            join jobTitle in _jobTitleRepository.GetAll().Where(j => !j.IsDeleted)
                                on doctor.JobTitleId equals jobTitle.Id
                            join registration in _registrationRepository.GetAll().Where(r => !r.IsDeleted)
                                on register.registrationId equals registration.Id into regGroup
                            from registration in regGroup.DefaultIfEmpty() // 左连接
                            select new
                            {
                                Register = register,
                                Patient = patient,
                                Doctor = doctor,
                                Department = department,
                                Campus = campus,
                                JobTitle = jobTitle,
                                Registration = registration
                            };

                // 执行查询
                var result = await query.FirstOrDefaultAsync(cancellationToken);

                // 如果未找到记录
                if (result == null)
                {
                    return new ApiResult<RegisterDetailDto>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "未找到该挂号记录"
                    };
                }

                // 组装DTO
                var dto = new RegisterDetailDto
                {
                    // 基本挂号信息
                    Id = result.Register.Id,                          // 挂号记录ID
                    PatientId = result.Register.PatientId,            // 患者ID，用于关联患者信息
                    PatientName = result.Patient.Name,                // 患者姓名
                    MedicalCardNumber = result.Patient.IdCard,        // 就诊卡号（使用患者身份证代替）
                    IdCardType = "身份证",                             // 证件类型，固定为身份证
                    IdCardNumber = result.Patient.IdCard,             // 身份证号码

                    // 患者相关信息
                    WechatName = result.Patient.WechatName,           // 患者微信昵称
                    PhoneNumber = result.Patient.Phone,               // 联系电话
                    Relation = result.Patient.Relation,               // 与患者的关系（如本人、家属等）
                    PatientAvatar = result.Patient.Avatar,            // 患者头像URL
                    PatientAddress = result.Patient.Address,          // 患者住址

                    // 医院和科室信息
                    HospitalName = result.Campus.CampusName,          // 医院/院区名称
                    HospitalAddress = result.Campus.CampusAddr,       // 医院地址
                    DepartmentName = result.Department.DepartmentName, // 科室名称

                    // 医生信息
                    DoctorName = result.Doctor.DoctorName,            // 医生姓名
                    DoctorTitle = result.JobTitle.JobTitle,           // 医生职称

                    // 挂号相关信息
                    RegisterType = result.Register.Type,              // 挂号类型（如专家号、普通号等）
                    RegisterFee = result.Register.Fee,                // 挂号费用
                    RegisterStatus = result.Register.Status,          // 挂号状态（如待就诊、已就诊、已取消）
                    CancelReason = result.Register.Reservecause,      // 取消原因（如有）
                    RegisterRemark = result.Register.RegisterRemark,  // 挂号备注

                    // 时间相关信息
                    VisitDate = result.Register.VisitDate,            // 就诊日期
                    WaitTime = result.Register.WaitTime,              // 候诊时间/预计等待时间
                    ReserveTime = result.Register.AppointmentTime,    // 预约时间
                    CancelTime = result.Register.Reservetime,         // 取消时间

                    // 号源相关信息
                    registrationId = result.Register.registrationId,  // 号源ID，关联号源表
                    // 号源序号，优先使用号源表中的序号，如为空则使用挂号表中的备用序号
                    slot_number = result.Registration != null ? result.Registration.slot_number : result.Register.slot_number
                };

                return new ApiResult<RegisterDetailDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "查询成功",
                    Data = dto
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询挂号详情异常");
                return new ApiResult<RegisterDetailDto>
                {
                    Code = ApiEnum.Error,
                    Msg = "查询异常：" + ex.Message
                };
            }
        }
    }
}